package cn.itcast.web.controller.system;

import cn.itcast.domain.system.Dept;
import cn.itcast.domain.system.Role;
import cn.itcast.domain.system.User;
import cn.itcast.service.system.DeptService;
import cn.itcast.service.system.RoleService;
import cn.itcast.service.system.UserService;
import cn.itcast.web.controller.BaseController;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/system/user")
public class UserController extends BaseController {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private DeptService deptService;

    @Autowired
    private RabbitTemplate rabbitTemplate ;

    /*
    方法的作用：展示用户列表
    url: /system/user/list.do
    参数： 当前页， 页面大小
    返回： system/user/user-list
     */
    @RequestMapping("/list")
    // @RequiresPermissions("用户管理")
    public String list(@RequestParam(defaultValue = "1") int pageNum,
                       @RequestParam(defaultValue = "10") int pageSize) {
        //添加权限检查的代码之后，则要求访问者必须拥有权限才能访问,使用硬编码的方式去检查权限
        // Subject subject = SecurityUtils.getSubject();
        // subject.checkPermission("用户管理");

        //1. 查询到pageInfo对象
        //companyId是指当前登陆者所属的公司id.
        String companyId = getLoginCompanyId();  //由于现在还有完成登陆功能，所以目前的数据只是写死。
        PageInfo<User> pageInfo = userService.findByPage(pageNum, pageSize, companyId);

        //2. 把PageInfo存储到域中
        request.setAttribute("pageInfo", pageInfo);
        //3. 返回到列表页面
        return "system/user/user-list";
    }

    /*
    方法的作用：进入添加用户的页面
    url: /system/user/toAdd.do
    参数： 无
    返回： system/user/user-add
     */
    @RequestMapping("toAdd")
    public String toAdd() {
        //1. 查询所有的用户信息，用于展示父用户的下拉框
        String companyId = getLoginCompanyId();
        List<Dept> deptList = deptService.findAll(companyId);
        //2. 把用户的信息存储到域中
        request.setAttribute("deptList", deptList);
        //3. 返回到添加页面
        return "system/user/user-add";
    }


    /*
    方法的作用：保存添加用户以及更新用户的信息
    url: /system/user/edit.do
    参数： user 对象
    返回： 用户列表
     */
    @RequestMapping("edit")
    public String toAdd(User user) {
        //设置当前用户所属的公司
        String companyId = getLoginCompanyId();
        String companyName = getLoginCompanyName();
        user.setCompanyId(companyId);
        user.setCompanyName(companyName);

        if (StringUtils.isEmpty(user.getId())) {
            //如果id为空，则为保存
            userService.save(user);
            //保存完用户，马上向mq发送消息
            // rabbitTemplate.convertAndSend("email-exchange","user.add",user);
        } else {
            //如果id不为空， 则为更新
            userService.update(user);
        }
        /*
            如果返回的路径带有redirect或者是forward是不经过视图解析器。
            路径：
                绝对路径:   不以/开头的路径都是相对路径 , 相对当前程序所在的路径,当前程序所在路径是会发生变化的。
                相对路径：  "/"那这种就是绝对路径
         */
        //这里的"/"代表  http://localhost8080/
        return "redirect:/system/user/list.do";
    }


    /*
   方法的作用：进入修改用户的页面
   url: /system/user/toUpdate.do?id=97f88a8c-90fc-4d52-aed7-2046f62fb498
   参数： id 用户的id
   返回： /system/user/user-update
    */
    @RequestMapping("toUpdate")
    public String toUpdate(String id) {
        String companyId = getLoginCompanyId();
        //1. 根据id查询一个用户对象，存储到域中
        User user = userService.findById(id);
        request.setAttribute("user", user);

        /*//2. 查询所有的用户对象，用于展示父用户列表，存储到域中
        List<User> userList = userService.findAll(companyId);
        request.setAttribute("userList", userList);
        //3. 返回用户更新页面
        return "/system/user/user-update";*/
        //2. 查询所有的用户对象，用于展示父用户列表，存储到域中
        List<Dept> deptList = deptService.findAll(companyId);
        request.setAttribute("deptList", deptList);
        //3. 返回用户更新页面
        return "/system/user/user-update";
    }

    /*
   方法的作用：删除用户
   url: /system/user/delete.do?id=97f88a8c-90fc-4d52-aed7-2046f62fb498
   参数： id 用户的id
   返回： json对象

   json = {flag:true|false , message:"删除成功|删除失败"}
    */
    @RequestMapping("delete")
    @ResponseBody // @ResponseBody 可以帮我买把返回值转换为json对象
    public Map<String, Object> delete(String id) {
        Map<String, Object> resultMap = new HashMap<>();
        boolean flag = userService.delete(id);
        if (flag) {
            //删除成功
            resultMap.put("flag", true);
            resultMap.put("message", "删除成功");
        } else {
            resultMap.put("flag", false);
            resultMap.put("message", "该用户被其他用户引用，不能删除");
        }
        return resultMap;
    }

    /**
     * 方法的作用：进入用户角色的页面
     * url: /system/user/roleList.do?id=002108e2-9a10-4510-9683-8d8fd1d374ef
     *
     * @param id
     * @return 用户角色页面 system/user/user-role.jsp
     */
    @RequestMapping("roleList")
    public String roleList(String id) {
        // 1.根据id查找用户,并且存储到域中
        User user = userService.findById(id);
        request.setAttribute("user", user);

        // 2.查询所有的角色
        List<Role> roleList = roleService.findAll(getLoginCompanyId());
        request.setAttribute("roleList", roleList);

        // 3.当前用户具备的角色
        List<Role> userRoleList = roleService.findUserRoleByUserId(id);
        request.setAttribute("userRoleList", userRoleList);
        return "system/user/user-role";
    }

    /**
     * 方法的作用：更新保存用户的角色
     * url: /system/user/changeRole.do
     *
     * @param userid  用户的id
     * @param roleIds 用户具备的角色id（数组）
     * @return 用户列表
     */
    @RequestMapping("changeRole")
    public String changeRole(String userid, String[] roleIds) {
        userService.changeRole(userid, roleIds);
        return "redirect:/system/user/list.do";
    }

}
